'use client';

import React from 'react';
import { TimelinePanel } from '../components/TimelinePanel';
import { TaskBoard } from '../components/TaskBoard';
import { NotificationsPanel } from '../components/NotificationsPanel';
import { ComposerDrawer } from '../components/ComposerDrawer';
import { CommentDrawer } from '../components/CommentDrawer';
import { CommandPalette, CommandItem } from '../components/CommandPalette';
import { AttachmentsViewer } from '../components/AttachmentsViewer';
import { AgentsSidebar } from '../components/AgentsSidebar';
import { RoutinePanel } from '../components/RoutinePanel';
import { ConversationPanel } from '../components/ConversationPanel';
import { apiClient, EventModel, TaskModel, AccountModel } from '../lib/api';
import { DEFAULT_OWNER } from '../lib/config';
import {
  mutateFeed,
  mutateTasks,
  useAccounts,
  useFeed,
  useMentions,
  useNotifications,
  useTasks,
  useFeedsForOwners
} from '../hooks/useAwData';

export default function Dashboard() {
  const [owner, setOwner] = React.useState(DEFAULT_OWNER);
  const actor = owner;
  const ALL_CHATS = '__ALL__';
  const { data: feed, isLoading: feedLoading, mutate: refreshFeed } = useFeed(owner);
  const { data: tasks, isLoading: tasksLoading, mutate: refreshTasks } = useTasks(owner);
  const { data: notifications, isLoading: notificationsLoading } = useNotifications(owner);
  const { data: mentions, isLoading: mentionsLoading } = useMentions(owner);
  const { data: accounts } = useAccounts();

  const [composerOpen, setComposerOpen] = React.useState(false);
  const [paletteOpen, setPaletteOpen] = React.useState(false);
  const [selectedAttachments, setSelectedAttachments] = React.useState<EventModel | null>(null);
  const [replyTarget, setReplyTarget] = React.useState<EventModel | null>(null);
  const [activeFriend, setActiveFriend] = React.useState<string>(ALL_CHATS);

  const initialFriendCandidates = React.useMemo(() => {
    if (!feed) return [] as string[];
    const set = new Set<string>();
    feed.forEach(event => {
      if (event.actor && event.actor !== owner) {
        set.add(event.actor);
      }
      const mentions = (event.headers['mentions'] ?? '')
        .split(/\s+/)
        .map(m => m.replace(/^@/, '').trim())
        .filter(Boolean);
      mentions.forEach(m => {
        if (m !== owner) set.add(m);
      });
    });
    return Array.from(set).sort((a, b) => a.localeCompare(b));
  }, [feed, owner]);

  const { data: friendEvents, isLoading: friendEventsLoading } = useFeedsForOwners(initialFriendCandidates, owner);

  const allEvents = React.useMemo(() => {
    const map = new Map<string, EventModel>();
    (feed ?? []).forEach(event => map.set(event.id, event));
    (friendEvents ?? []).forEach(event => map.set(event.id, event));
    return Array.from(map.values()).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
  }, [feed, friendEvents]);

  const friends = React.useMemo(() => {
    const set = new Set<string>();
    allEvents.forEach(event => {
      if (event.actor && event.actor !== owner) {
        set.add(event.actor);
      }
      const mentions = (event.headers['mentions'] ?? '')
        .split(/\s+/)
        .map(m => m.replace(/^@/, '').trim())
        .filter(Boolean);
      mentions.forEach(m => {
        if (m !== owner) set.add(m);
      });
    });
    (accounts ?? []).forEach(acc => {
      if (acc.id !== owner) {
        set.add(acc.id);
      }
    });
    return Array.from(set).sort((a, b) => a.localeCompare(b));
  }, [allEvents, owner, accounts]);

  React.useEffect(() => {
    setActiveFriend(ALL_CHATS);
  }, [owner]);

  const accountMap = React.useMemo(() => {
    const map: Record<string, AccountModel> = {};
    (accounts ?? []).forEach(acc => {
      map[acc.id] = acc;
    });
    return map;
  }, [accounts]);

  const cycleSpace = React.useCallback(() => {
    if (!accounts || accounts.length === 0) return;
    const index = accounts.findIndex(acc => acc.id === owner);
    const next = accounts[(index + 1) % accounts.length];
    setOwner(next.id);
    setActiveFriend(ALL_CHATS);
  }, [accounts, owner]);

  React.useEffect(() => {
    const handler = (event: KeyboardEvent) => {
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') {
        event.preventDefault();
        setPaletteOpen(true);
        return;
      }
      if ((event.metaKey || event.ctrlKey) && event.key === ']') {
        event.preventDefault();
        cycleSpace();
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [cycleSpace]);

  const commands: CommandItem[] = [
    {
      id: 'new-post',
      label: 'Compose new post',
      shortcut: '⌘K → enter',
      action: () => setComposerOpen(true)
    },
    {
      id: 'refresh-feed',
      label: 'Refresh feed',
      shortcut: 'R',
      action: () => refreshFeed()
    },
    {
      id: 'refresh-tasks',
      label: 'Refresh tasks',
      action: () => refreshTasks()
    },
    {
      id: 'next-space',
      label: 'Switch to next space',
      shortcut: '⌘/Ctrl + ]',
      action: cycleSpace
    },
    {
      id: 'open-documentation',
      label: 'Open API docs',
      action: () => {
        window.open('https://fastapi.tiangolo.com/', '_blank');
      }
    }
  ];

  async function handlePost(payload: { message: string; tags: string[]; mentions: string[]; files: File[] }) {
    await apiClient.createPost(owner, actor, payload.message, {
      tags: payload.tags,
      mentions: payload.mentions,
      files: payload.files
    });
    await mutateFeed(owner);
  }

  function handleReply(event: EventModel) {
    setReplyTarget(event);
  }

  async function submitComment(message: string, mentions: string[]) {
    if (!replyTarget) return;
    const mentionSuffix = mentions.length ? `\n\n${mentions.map(m => `@${m}`).join(' ')}` : '';
    await apiClient.createComment(owner, actor, replyTarget.id, `${message}${mentionSuffix}`);
    await mutateFeed(owner);
  }

  async function handleMoveTask(task: TaskModel, status: string) {
    if (task.status === status) return;
    await apiClient.updateTaskStatus(owner, task.id, actor, status);
    await mutateTasks(owner);
  }

  React.useEffect(() => {
    const unsubscribe = apiClient.subscribeFeed(owner, payload => {
      if (!payload || typeof payload !== 'object') return;
      const message = payload as { type?: string; events?: unknown };
      if (message.type === 'snapshot' && Array.isArray(message.events)) {
        refreshFeed(message.events as EventModel[], false);
        refreshTasks();
        return;
      }
      if (message.type === 'heartbeat') {
        refreshFeed();
        refreshTasks();
      }
    });
    return () => unsubscribe();
  }, [owner, refreshFeed, refreshTasks]);

  return (
    <>
      <header className="top-bar">
        <div>
          <h1>Agent Space</h1>
          <span className="muted">Reading routines from {owner}</span>
        </div>
        <div className="top-actions">
          <button className="ghost" onClick={() => setComposerOpen(true)}>New post</button>
          <button className="ghost" onClick={() => setPaletteOpen(true)}>Command palette</button>
        </div>
      </header>
      <main className="layout-grid">
        <AgentsSidebar accounts={accounts} currentOwner={owner} onSelectOwner={setOwner} />
        <div className="center-column">
          <ConversationPanel
            owner={owner}
            friends={friends}
            accountMap={accountMap}
            activeFriend={activeFriend}
            onSelectFriend={setActiveFriend}
            events={allEvents}
            loading={feedLoading || friendEventsLoading}
          />
          <TimelinePanel
            events={feed}
            loading={feedLoading}
            onRefresh={() => refreshFeed()}
            onReply={handleReply}
            onViewAttachments={setSelectedAttachments}
          />
        </div>
        <div className="right-column">
          <RoutinePanel events={feed} />
          <TaskBoard tasks={tasks} loading={tasksLoading} onMove={handleMoveTask} />
          <NotificationsPanel
            notifications={notifications}
            mentions={mentions}
            loading={notificationsLoading || mentionsLoading}
          />
        </div>
      </main>
      <ComposerDrawer
        open={composerOpen}
        owner={owner}
        actor={actor}
        onClose={() => setComposerOpen(false)}
        onSubmit={handlePost}
      />
      <CommentDrawer
        target={replyTarget}
        actor={actor}
        onClose={() => setReplyTarget(null)}
        onSubmit={submitComment}
      />
      <AttachmentsViewer event={selectedAttachments} onClose={() => setSelectedAttachments(null)} />
      <CommandPalette commands={commands} open={paletteOpen} onClose={() => setPaletteOpen(false)} />
    </>
  );
}
